<?php
/**
 * EGP Framework
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */

!defined('EGP_LIB_DIR') && die('Access Deny!');

/**
 * UBB 处理
 *
 * @package    classes
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */
class EGP_Text_Ubb
{

    /**
     * UBB 配置
     *
     * @var array
     */
    protected $_config = array(
        'font'   => true,
        'link'   => true,
        'image'  => true,
        'list'   => true,
        'format' => true,
        'flash'  => true,
        'media'  => true,
        'smile'  => true,
    );

    /**
     * UBB 表情参数
     *
     * @example array(array('match' => '[cool]', 'image' => '/smiles/cool.gif', 'alt' => '耍酷'))
     * @var array
     */
    protected $_smiles = array();

    /**
     * 构造方法
     *
     * @param  array  $config
     * @param  array  $smiles
     */
    public function __construct(array $config = array(), array $smiles = array())
    {
        foreach ($config as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (method_exists($this, $method)) {
                $this->$method($value);
            }
        }
        $this->_smiles = $smiles;
    }

    /**
     * 设置是否使用字体标签
     *
     * @param  bool  $bool
     * @return EGP_Text_Ubb
     */
    public function setFont($bool)
    {
        $this->_config['font'] = (boolean) $bool;
        return $this;
    }

    /**
     * 设置是否使用链接标签
     *
     * @param  bool  $bool
     * @return EGP_Text_Ubb
     */
    public function setLink($bool)
    {
        $this->_config['link'] = (boolean) $bool;
        return $this;
    }

    /**
     * 设置是否使用图像标签
     *
     * @param  bool  $bool
     * @return EGP_Text_Ubb
     */
    public function setImage($bool)
    {
        $this->_config['image'] = (boolean) $bool;
        return $this;
    }

    /**
     * 设置是否使用列表标签
     *
     * @param  bool  $bool
     * @return EGP_Text_Ubb
     */
    public function setList($bool)
    {
        $this->_config['list'] = (boolean) $bool;
        return $this;
    }

    /**
     * 设置是否使用格式化文本标签
     *
     * @param  bool  $bool
     * @return EGP_Text_Ubb
     */
    public function setFormat($bool)
    {
        $this->_config['format'] = (boolean) $bool;
        return $this;
    }

    /**
     * 设置是否使用 FLASH 标签
     *
     * @param  bool  $bool
     * @return EGP_Text_Ubb
     */
    public function setFlash($bool)
    {
        $this->_config['flash'] = (boolean) $bool;
        return $this;
    }

    /**
     * 设置是否使用媒体标签
     *
     * @param  bool  $bool
     * @return EGP_Text_Ubb
     */
    public function setMedia($bool)
    {
        $this->_config['media'] = (boolean) $bool;
        return $this;
    }

    /**
     * 设置是否使用表情标签
     *
     * @param  bool  $bool
     * @return EGP_Text_Ubb
     */
    public function setSmile($bool)
    {
        $this->_config['smile'] = (boolean) $bool;
        return $this;
    }

    /**
     * 配置 UBB 表情解析
     *
     * @param  array  $params
     * @return EGP_Text_Ubb
     */
    public function setSmiles(array $params=  array())
    {
        $this->_smiles = array_merge($this->_smiles, $params);
        return $this;
    }

    /**
     * 对 UBB 字体标签解码
     *
     * @param  string  $text
     * @return string
     */
    protected function _font($text)
    {
        $pattern = array(
            '/\[h1\]\s*(.+?)\[\/h1\]/is',
            '/\[h2\]\s*(.+?)\[\/h2\]/is',
            '/\[h3\]\s*(.+?)\[\/h3\]/is',
            '/\[h4\]\s*(.+?)\[\/h4\]/is',
            '/\[h5\]\s*(.+?)\[\/h5\]/is',
            '/\[h6\]\s*(.+?)\[\/h6\]/is',
            '/\[b\]\s*(.+?)\[\/b\]/is',
            '/\[u\]\s*(.+?)\[\/u\]/is',
            '/\[i\]\s*(.+?)\[\/i\]/is',
            '/\[s\]\s*(.+?)\[\/s\]/is',
            '/\[del\]\s*(.+?)\[\/del\]/is',
            '/\[strike\]\s*(.+?)\[\/strike\]/is',
            '/\[size=\s*(.+?)\]\s*(.+?)\[\/size\]/is',
            '/\[color=\s*(.+?)\]\s*(.+?)\[\/color]/is',
            '/\[back=\s*(.+?)\]\s*(.+?)\[\/back]/is',
            '/\[font=\s*(.+?)\]\s*(.+?)\[\/font\]/is',
            '/\[sub\]\s*(.+?)\[\/sub\]/is',
            '/\[sup\]\s*(.+?)\[\/sup\]/is',
            '/\[left\]\s*(.+?)\[\/left\]/is',
            '/\[center\]\s*(.+?)\[\/center\]/is',
            '/\[right\]\s*(.+?)\[\/right\]/is',
            '/\[justify\]\s*(.+?)\[\/justify\]/is',
            '/\[align\s*=\s*(\S+?)\s*\](.*?)\[\/align\]/is',
            //----------------------------------------------
            '/\[fly\]\s*(.+?)\[\/fly\]/is',
            '/\[fly=([a-z][A-Z]+)\]\s*(.+?)\[\/fly\]/is',
            '/\[fly=(\S+?),(\S+?),(\S+?)\]\s*(.+?)\[\/fly\]/is',
            '/\[move\]\s*(.+?)\[\/move\]/is',
            '/\[shadow=(\S+?),([0-9]+),([0-9]+)\s*\](.*?)\[\/shadow\]/is',
            '/\[glow=(\S+?),([0-9]+)\s*\](.*?)\[\/glow\]/is',
            '/\[fliph\](.+?)\[\/fliph\]/is',
            '/\[flipv\](.+?)\[\/flipv\]/is',
            '/\[blur\](.*?)\[\/blur\]/is',
            '/\[dropshadow=(\S+?)\s*\](.*?)\[\/dropshadow\]/is',
            '/\[invert\](.*?)\[\/invert\]/is',
            '/\[xray\](.*?)\[\/xray\]/is',
        );
        $replace = array(
            '<h1>\\1</h1>',
            '<h2>\\1</h2>',
            '<h3>\\1</h3>',
            '<h4>\\1</h4>',
            '<h5>\\1</h5>',
            '<h6>\\1</h6>',
            '<strong>\\1</strong>',
            '<u>\\1</u>',
            '<em>\\1</em>',
            '<del>\\1</del>',
            '<del>\\1</del>',
            '<del>\\1</del>',
            '<font size="\\1">\\2</font>',
            '<span style="color:\\1">\\2</span>',
            '<span style="background:\\1">\\2</span>',
            '<span style="font-family:\\1">\\2</span>',
            '<sub>\\1</sub>',
            '<sup>\\1</sup>',
            '<div align="left">\\1</div>',
            '<div align="center">\\1</div>',
            '<div align="right">\\1</div>',
            '<div align="justify">\\1</div>',
            '<div align="\\1">\\2</div>',
            //----------------------------------------------
            '<marquee behavior="alternate">\\1</marquee>',
            '<marquee direction="\\1" behavior="alternate">\\2</marquee>',
            '<marquee direction="\\1" width="\\2" height="\\3" behavior="alternate">\\4</marquee>',
            '<marquee>\\1</marquee>',
            '<font style="width=100%; filter:shadow(color=\\1,direction=\\2,strength=\\3)" >\\4</font>',
            '<font style="width=80%; filter:glow\(color=\\1,strength=\\2)">\\3</font>',
            '<font style="width=80%; filter:flipH">\\1</font>',
            '<font style="width=80%; filter:flipV">\\1</font>',
            '<font style="width=80%; filter:blur">\\1</font>',
            '<font style="width=80%; filter:dropshadow(color=\\1)">\\2</font>',
            '<font style="width=80%; filter:invert">\\2</font>',
            '<font style="width=80%; filter:xray">\\2</font>',
        );
        return preg_replace($pattern, $replace, $text);
    }

    /**
     * 对 UBB 链接标签解码
     *
     * @param  string  $text
     * @return string
     */
    protected function _link($text)
    {
        $pattern = array(
            '/\[url\]\s*(.+?)\[\/url\]/is',
            '/\[url=\s*(.+?)\]\s*(.+?)\[\/url\]/is',
            '/\[url\]www\.\s*(.+?)\[\/url\]/is',
            '/\[email\]\s*(.+?)\[\/email\]/is',
            '/\[email=\s*(.+?)\]\s*(.+?)\[\/email\]/is',
        );
        $replace = array(
            '<a href="\\1" target="_blank">\\1</a>',
            '<a href="\\1" target="_blank">\\2</a>',
            '<a href="http://www.\\1" target="_blank">\\1</a>',
            '<a href="mailto:\\1">\\1</a>',
            '<a href="mailto:\\1">\\2</a>',
        );
        return preg_replace($pattern, $replace, $text);
    }

    /**
     * 对 UBB 图像标签解码
     *
     * @param  string  $text
     * @return string
     */
    protected function _image($text)
    {
        $pattern = array(
            '/\[img\]\s*(.+?)\[\/img\]/is',
            '/\[img=(\d+),\s*(\d+)\]\s*(.+?)\[\/img\]/is',
        );
        $replace = array(
            '<a href="\\1" target="_blank" class="ubb-img"><img src="\\1" border="0" alt="" /></a>',
            '<a href="\\3" target="_blank" class="ubb-img"><img src="\\3" border="0" height="\\2" width="\\1" alt="" /></a>',
        );
        return preg_replace($pattern, $replace, $text);
    }

    /**
     * 对 UBB 列表标签解码
     *
     * @param  string  $text
     * @return string
     */
    protected function _list($text)
    {
        $pattern = array(
            '/\[list\]\s*(.+?)\[\/list\]/is',
            '/\[\*\]\s*([^\[]*)/is',
            '/\[list\]\s*(.+?)\[\/list:u\]/is',
            '/\[list=1\]\s*(.+?)\[\/list\]/is',
            '/\[list=i\]\s*(.+?)\[\/list\]/is',
            '/\[list=I\]\s*(.+?)\[\/list\]/is',
            '/\[list=a\]\s*(.+?)\[\/list\]/is',
            '/\[list=A\]\s*(.+?)\[\/list\]/is',
            '/\[list\]\s*(.+?)\[\/list:o\]/is',
        );
        $replace = array(
            '<ul>\\1</ul>',
            '<li>\\1</li>',
            '<ul>\\1</ul>',
            '<ol style="list-style-type:decimal;">\\1</ol>',
            '<ol style="list-style-type:lower-roman;">\\1</ol>',
            '<ol style="list-style-type:upper-roman;">\\1</ol>',
            '<ol style="list-style-type:lower-alpha;">\\1</ol>',
            '<ol style="list-style-type:upper-alpha;">\\1</ol>',
            '<ol style="list-style-type:decimal;">\\1</ol>',
        );
        return preg_replace($pattern, $replace, $text);
    }

    /**
     * 对 UBB 格式标签解码
     *
     * @param  string  $text
     * @return string
     */
    protected function _format($text)
    {
        $pattern = array(
            '/\[p\]/is',
            '/\[\/p\]/is',
            '/\[hr\]/is',
            '/\[pre\]\s*(.+?)\[\/pre\]/is',
            '/\[quote\]\s*(.+?)\[\/quote\]/is',
            '/\[code\]\s*(.+?)\[\/code\]/is',
        );
        $replace = array(
            '<p>',
            '</p>',
            '<hr size="1" />',
            '<pre>\\1</pre>',
            '<div class="ubb-quote"><div class="ubb-quote-title">QUOTE：</div><div class="ubb-quote-content">\\1</div></div>',
            '<div class="ubb-code"><div class="ubb-code-title">CODE：</div><div class="ubb-code-content">\\1</div></div>',
        );
        return preg_replace($pattern, $replace, $text);
    }

    /**
     * 对 UBB Flash 标签解码
     *
     * @param  string  $text
     * @return string
     */
    protected function _flash($text)
    {
        $pattern = array(
            '/\[flash\]\s*(.+?)\[\/flash\]/is',
            '/\[flash=(\d+),\s*(\d+)\]\s*(.+?)\[\/flash\]/is',
        );
        $replace = array(
            '<embed src="\\1" quality="high" width="400" height="300" type="application/x-shockwave-flash"></embed>',
            '<embed src="\\3" quality="high" width="\\1" height="\\2" type="application/x-shockwave-flash"></embed>',
        );
        return preg_replace($pattern, $replace, $text);
    }

    /**
     * 对 UBB 媒体标签解码
     *
     * @param  string  $text
     * @return string
     */
    protected function _media($text)
    {
        $pattern = array(
            '/\[media\]\s*(.+?)\[\/media\]/is',
            '/\[media=(\d+),\s*(\d+)\]\s*(.+?)\[\/media\]/is',
        );
        $replace = array(
            '<embed src="\\1" quality="high" width="400" height="300" enablecontextmenu="false" autostart="false" type="application/x-mplayer2"></embed>',
            '<embed src="\\3" quality="high" width="\\1" height="\\2" enablecontextmenu="false" autostart="false" type="application/x-mplayer2"></embed>',
        );
        return preg_replace($pattern, $replace, $text);
    }

    /**
     * 对 UBB 表情标签解码
     *
     * @param  string  $text
     * @return string
     */
    protected function _smile($text)
    {
        foreach ($this->_smiles as $param) {
            $image = '<img src="' . @$param['image'] . '" alt="' . @$param['alt'] . '" border="0" />';
            $text = str_ireplace(@$param['match'], $image, $text);
        }
        return $text;
    }

    /**
     * 对文本进行 UBB 解码
     *
     * @param  string  $text
     * @return string
     */
    public function decode($text)
    {
        foreach ($this->_config as $key => $value) {
            $method = "_$key";
            if ($value && method_exists($this, $method)) {
                $text = $this->$method($text);
            }
        }
        return $text;
    }

}